import * as THREE from "three";
import ContextMenu, { type MenuItem } from "@imengyu/vue3-context-menu";
import { BaseMode } from "./BaseMode";
import { InitMode } from "./InitMode";
import {
  DisplayKujialeAssemblyModelAndInvisibleOthers,
  changeMode,
  fitCameraToObject,
} from "..";
import {
  Part3DMesh,
  Loft3DMesh,
  MouseSenseCube,
} from "../types/DrawingGroups/meshs";
import {
  AssemblyProductGroup,
  Product3DGroup,
  Sub3DGroup,
  Base3DGroup
} from "../types/DrawingGroups/groups";
import type { KujialeAssemblyModel } from "../types/KujialeJsonModels/KujialeAssemblyModel";
import type { AssemblyProductModel } from "../types/Models";
import { useJsonStore } from "@/stores/json";
import { useCurrentModelStore } from "@/stores/current";
import { SingleProductMode } from "./SingleProductMode";

export class SingleAssemblyProductMode extends BaseMode {
  model: KujialeAssemblyModel;

  constructor(
    dom: HTMLCanvasElement,
    camera: THREE.Camera,
    scene: THREE.Scene,
    am: KujialeAssemblyModel
  ) {
    super(dom, camera, scene);
    this.modeName = "single product";
    this.model = am;

    //this.init();
  }

  init() {
    var r = DisplayKujialeAssemblyModelAndInvisibleOthers(this.model);
    if (r.effectGroup) {
      const store = useCurrentModelStore();
      store.setCurrentModel([r.effectGroup as Base3DGroup]);
      //fitCameraToObject(r.effectGroup);
    }
    this.mouseSenseCubes = this.findMouseSenseCubes();
  }

  mousemove(e: MouseEvent) {
    this.funcRaycaster(e);
  }

  mousedown(e: MouseEvent) {
    var storeCurrent = useCurrentModelStore();
    if (this.currentProductCube && this.currentProductCube.visible) {
      if (this.currentProductCube.parent instanceof Product3DGroup) {
        storeCurrent.setCurrentModel([this.currentProductCube.parent as Product3DGroup]);
        storeCurrent.setCurrentRightTabName("model");
        
        var basemodel = this.currentProductCube.parent.model;
        var [model] = this.currentProductCube.parent.model.kujialeModel!;
        var store = useJsonStore();
        store.setCurrentJson(model);

        ContextMenu.showContextMenu({
          x: e.x,
          y: e.y,
          items: [
            {
              label: model.modelName,
              children: this.getCurrentModelInfoMenuItems(),
            },
            {
              label: "材质",
              children: this.getCurrentMenuTextureList(),
            },
            {
              label: basemodel.doorClosed ? "开门" : "关门",
              onClick: this.findDoorsAndAction.bind(this, basemodel.doorClosed, () => {
                basemodel.doorClosed = !basemodel.doorClosed;
              }),
            },
            {
              label: "检视",
              onClick: () => {
                changeMode(
                  new SingleProductMode(
                    this.dom,
                    this.camera,
                    this.scene,
                    this.currentProductCube?.parent as Product3DGroup,
                    this
                  ),
                  true
                );
              },
            },
            {
              label: "JSON",
              onClick:()=>{
                storeCurrent.setCurrentRightTabName("json");
              }
            }
          ],
        });
      }
    }
  }

  contextmenu(e: MouseEvent): void {
    ContextMenu.showContextMenu({
      x: e.x,
      y: e.y,
      items: [
        {
          label: "退回",
          onClick: () => {
            changeMode(new InitMode(this.dom, this.camera, this.scene), false);
          },
        },
      ],
    });
  }

  onStepInMode(): void {
    if (this.currentProductCube) {
      this.currentProductCube.visible = false;
    }
  }

  onExitMode(): void {
    if (this.currentProductCube) {
      this.currentProductCube.visible = false;
    }

    this.scene.children.forEach((g) => {
      if (g instanceof Product3DGroup || g instanceof AssemblyProductGroup) {
        g.visible = true;
      } else if (g instanceof MouseSenseCube) {
        g.visible = false;
      }
    });
  }

  findMouseSenseCubes(): THREE.Mesh[] {
    const meshes: THREE.Mesh[] = [];
    this.scene.children.forEach((g) => {
      if (
        g instanceof AssemblyProductGroup &&
        (g.model as AssemblyProductModel).kujialeAssemblyModel == this.model
      ) {
        g.children.forEach((s) => {
          if (s instanceof Product3DGroup || s instanceof Sub3DGroup) {
            if (s.children.length > 0 && s.children[0] instanceof THREE.Mesh) {
              meshes.push(s.children[0] as THREE.Mesh);
            }
          }
        });
      }
    });
    return meshes;
  }
}
